package com.ant.storage.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.ant.storage.common.ResultCode;
import com.ant.storage.common.ResultVo;
import com.ant.storage.dto.HouseLeaseDto;
import com.ant.storage.excel.HouseLeaseExcel;
import com.ant.storage.handler.AntException;
import com.ant.storage.mapper.HouseLeaseMapper;
import com.ant.storage.mapper.InvoiceInfoMapper;
import com.ant.storage.mapper.UserCityMapper;
import com.ant.storage.pojo.*;
import com.ant.storage.service.*;
import com.ant.storage.utils.DateFormat;
import com.ant.storage.utils.RandomUtil;
import com.ant.storage.wechat.WeChatUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletContext;
import java.io.File;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author melon
 * @since 2023-11-13
 */
@Service
public class HouseLeaseServiceImpl extends ServiceImpl<HouseLeaseMapper, HouseLease> implements IHouseLeaseService {

    @Autowired
    public ServletContext servletContext;

    @Autowired
    public IHouseAccountService accountService;

    @Autowired
    public IHouseContactsService contactsService;

    @Autowired
    public IHouseSettlementService settlementService;

    @Autowired
    public IPurchaserRecordImgService imgService;

    @Resource
    private IAuditListService auditListService;

    @Resource
    private IHouseLeaseService leaseService;

    @Resource
    private IInvoiceInfoService infoService;

    @Resource
    private InvoiceInfoMapper infoMapper;

    @Resource
    private UserCityMapper userCityMapper;

    @Autowired
    public IApprovalMsgService approvalMsgService;

    @Override
    public PageInfo<HouseLease> queryList(HouseLeaseDto dto) {
        try {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            PageHelper.startPage(dto.getPageIndex(), dto.getPageSize());
            QueryWrapper<HouseLease> wrapper = new QueryWrapper<>();
            if (dto.getCityId() != null) {
                wrapper.lambda().eq(HouseLease::getCityId, dto.getCityId());
            }
            if (dto.getCompanyId() != null) {
                wrapper.lambda().eq(HouseLease::getCompanyId, dto.getCompanyId());
            }
            if (StringUtils.isNotEmpty(dto.getContractNumber())) {
                wrapper.lambda().eq(HouseLease::getContractNumber, dto.getContractNumber());
            }
            if (dto.getContractStatus() != null) {
                wrapper.lambda().eq(HouseLease::getContractStatus, dto.getContractStatus());
            }
            if (dto.getContractType() != null) {
                wrapper.lambda().eq(HouseLease::getContractType, dto.getContractType());
            }
            if (dto.getTime() != null && dto.getTime().size() > 0) {
                wrapper.lambda().between(HouseLease::getDeadline,
                        dto.getTime().get(0) + " 00:00:00",
                        dto.getTime().get(1) + " 23:59:59");
            }

            if (dto.getFeeDue() != null && dto.getFeeDue().size() > 0) {
                wrapper.lambda().between(HouseLease::getFeeDue,
                        dto.getFeeDue().get(0) + " 00:00:00",
                        dto.getFeeDue().get(1) + " 23:59:59");
            }
            if (userInfo.getRoles() == null) {
                wrapper.lambda().eq(HouseLease::getCityId, userInfo.getCityId());
                wrapper.lambda().eq(HouseLease::getCreateBy, userInfo.getNameId());
            }
            if (userInfo.getRoles() != null && userInfo.getRoles().equals("admin")) {
                wrapper.lambda().in(HouseLease::getCityId, cityList(userInfo.getId()));
            }
            wrapper.eq("take_effect", 1);
            wrapper.orderByDesc("id");
            List<HouseLease> list = this.baseMapper.selectList(wrapper);
            list.stream().map(item -> {
                List<HouseContacts> contactsList = contactsService.list(new QueryWrapper<HouseContacts>().eq("parent_id"
                        , item.getId()));
                item.setHouseContactsList(contactsList);
                if (item.getDepositAnnex() != null) {
                    List<PurchaserRecordImg> imgList1 = imgService.list(new QueryWrapper<PurchaserRecordImg>()
                            .in("id", item.getDepositAnnex().split(",")));
                    item.setDepositAnnexList(imgList1);
                }
                return item;
            }).collect(Collectors.toList());

            PageInfo<HouseLease> pageInfo = new PageInfo<>(list);
            return pageInfo;
        } catch (Exception e) {
            throw new AntException(ResultCode.BODY_NOT_MATCH);
        }
    }

    /**
     * 走钉钉
     *
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo houseLeaseSave(HouseLease dto) {
        synchronized (this) {
            if (dto.getInvoiceType() == null) {
                throw new AntException(ResultCode.NOT_FOUND.getResultCode(), "请选择类型");
            }
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            dto.setContractNumber("HT" + RandomUtil.getOrderNumbers(this.baseMapper.selectLastID()));
            dto.setCreateBy(userInfo.getNameId().toString());
            dto.setCreationTime(new Date());
            this.baseMapper.insert(dto);

            dto.getHouseContactsList().stream().forEach(item -> {
                item.setParentId(dto.getId());
                contactsService.save(item);
            });
            dto.getHouseAccountList().stream().forEach(item -> {
                item.setParentId(dto.getId());
                accountService.save(item);
            });
            Integer infoId = saveInvoiceInfo(dto, dto.getHouseAccountList().get(0));
            saveHouseSettlement(dto);
            if (dto.getIsApproved() == 1) {
                // 添加审核
                AuditList auditList = new AuditList();
                auditList.setParentId(infoId);
                auditList.setProcessType("funds");
                auditList.setCreationTime(new Date());
                auditList.setName(userInfo.getNameId().toString());
                // 添加审核记录
                for (String str : dto.getApproval()) {
                    auditList.setNameId(str);
                    auditList.setTypes("1");
                    auditListService.save(auditList);
                }
                for (String str2 : dto.getNotify()) {
                    auditList.setNameId(str2);
                    auditList.setTypes("2");
                    auditListService.save(auditList);
                }
                //图片
                try {
                    String str = addWeChatData(dto);
                    ApprovalMsg msg=new ApprovalMsg();
                    msg.setParentId(infoId);// 申请列表id;
                    msg.setApprovalType("funds");
                    msg.setApprovalUser(userInfo.getUserName());
                    msg.setApprovalUserId(userInfo.getNameId());
                    msg.setSpNo(str);
                    msg.setCreationTime(new Date());
                    approvalMsgService.save(msg);
//                    //发起钉钉审
//                    FundsDto ding = new FundsDto();
//                    ding.setAccess_token(DingDingUtil.obtainToken());
//                    ding.setOriginator_userid(userInfo.getDingTalk());
//                    ding.setDeptId(userInfo.getDepId());
//                    ding.setId(dto.getId());
//                    ding.setApprover_userid(dto.getApproval());
//                    ding.setCc_userId(dto.getNotify());
//                    ding.setCity(userInfo.getCityId().toString());
//                    ding.setDate(DateFormat.getCurrentDates());
//                    ding.setUrgency(dto.getAccountUrgency());
//                    ding.setAmount(dto.getPaymentAmount().toString());
//                    ding.setPicture(null); // 图片
//                    ding.setCompanyName(userInfo.getDepName());
//                    ding.setReason(dto.getNotes());
//                    List<ReimbursementProjectDto> dataList = new ArrayList<>();
//                    ReimbursementProjectDto reimbursementProjectDto = new ReimbursementProjectDto();
//                    if (dto.getInvoiceType() == 2) {
//                        reimbursementProjectDto.setProjectName("房租费续费");
//                    } else {
//                        reimbursementProjectDto.setProjectName("房租费");
//                    }
//                    reimbursementProjectDto.setProjectPrice(dto.getPaymentAmount());
//                    dataList.add(reimbursementProjectDto);
//                    ding.setProjectDtoList(dataList);
//                    String process_instance_id = DingDingUtil.OldRequestFunds(ding);
//                    if (process_instance_id.equals("201")) {
//                        throw new AntException(ResultCode.FAILURE.getResultCode(), "钉钉提交失败");
//                    }
                    leaseService.update(new UpdateWrapper<HouseLease>()
                            .set("process_instance_id", str)
                            .eq("id", dto.getId()));
                    infoService.update(new UpdateWrapper<InvoiceInfo>().set(
                            "process_instance_id", str)
                            .eq("id", infoId));
                    return ResultVo.success("操作成功");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return ResultVo.success("操作成功");
        }
    }


    @SneakyThrows
    @Transactional(rollbackFor = Exception.class)
    public String addWeChatData(HouseLease dto) throws AntException {
        InvoiceInfo info = new InvoiceInfo();
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        info.setWeChat(userInfo.getWeChat());
        info.setUserName(userInfo.getUserName());
     //   reimbursementProjectDto.setProjectName("房租费续费");
        info.setInvoiceName(dto.getContractName());
        info.setReimbursementTypeText("房租费用申请");
        info.setApproval(dto.getApproval());
        info.setNotify(dto.getNotify());
        info.setInvoicePrice(new BigDecimal(dto.getPaymentAmount().toString()));
        info.setStartTime(DateFormat.simpleDateFormats(dto.getStartTime()));
        info.setEndTime(DateFormat.simpleDateFormats(dto.getDeadline()));
        info.setInvoiceNotes(dto.getNotes());
        info.setAccountName(dto.getHouseAccountList().get(0).getAccountName());
        info.setAccountNumber(dto.getHouseAccountList().get(0).getAccountNumber());
        info.setAccountBank(dto.getHouseAccountList().get(0).getAccountBank());
        List<ReimburseDetail> list = new ArrayList<>();
        ReimburseDetail detail = new ReimburseDetail();
        detail.setProjectName(dto.getContractName());
        detail.setProjectAmount("1");
        detail.setProjectUnit("间");
        detail.setProjectPrice(dto.getPaymentAmount());
        list.add(detail);
        info.setDetailList(list);
        String str = WeChatUtils.launchWeChatData(info);
        return str;
    }

    public String findUpload(String imgs) {
        File newFile = new File(imgs);
        String str = WeChatUtils.upload("image", null, newFile);
        JSONObject jsonObject =JSONObject.parseObject(str);
        String errcode = jsonObject.getString("errcode");
        if (StringUtils.isNotEmpty(errcode) && errcode.equals("0")) {
            String media_id = jsonObject.getString("media_id");
            return media_id;
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo houseLeaseSaves(HouseLease dto) {
        synchronized (this) {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            dto.setContractNumber("HT" + RandomUtil.getOrderNumbers(this.baseMapper.selectLastID()));
            dto.setCreateBy(userInfo.getNameId().toString());
            dto.setCreationTime(new Date());
            this.baseMapper.insert(dto);
            dto.getHouseContactsList().stream().forEach(item -> {
                item.setParentId(dto.getId());
                contactsService.save(item);
            });
            dto.getHouseAccountList().stream().forEach(item -> {
                item.setParentId(dto.getId());
                accountService.save(item);
            });
            return ResultVo.success("操作成功");
        }
    }

    @Override
    public List<HouseLeaseExcel> exportCensus(Integer isRecycle) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        Integer cityId = null;
        if(userInfo==null){
            cityId=null;
        }else if(userInfo.getRoles().equals("vadmin") || userInfo.getRoles().equals("admin")){
            cityId=null;
        } else{
            cityId=userInfo.getCityId();
        }
        List<HouseLeaseExcel> list = this.baseMapper.exportCensus(isRecycle, cityId);
        list.stream().forEach(item -> {
            item.setContractStatus(item.getContractStatus().equals("0") ? "到期" : "正常");
        });
        return list;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultVo houseLeaseUpdate(HouseLease dto) {
        synchronized (this) {
            UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
            //判断时间大于当日
            if (dto.getDeadline().after(new Date())) {
                dto.setContractStatus(1);
            }else{
                dto.setContractStatus(0);
            }
            this.baseMapper.updateById(dto);
            return ResultVo.success("操作成功");
        }
    }

    public List<String> getImg(String arr) {
        //遍历获取图片路径
        List<PurchaserRecordImg> imgList = imgService.list(new
                QueryWrapper<PurchaserRecordImg>().in("id", Arrays.asList(arr.split(","))));
        List<String> str = imgList.stream().map(p -> p.getUrl()).collect(Collectors.toList());
        return str;
    }

    public Integer saveInvoiceInfo(HouseLease dto, HouseAccount account)  {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        InvoiceInfo info = new InvoiceInfo();
        info.setHouseLeaseId(dto.getId());
        info.setCityId(dto.getCityId());
        info.setDepId(dto.getCompanyId());
        info.setInvoiceNumber("QK" + RandomUtil.getOrderNumbers(infoMapper.selectLastID()));
        info.setInvoiceName(dto.getContractName());
        info.setInvoiceType(1);
        info.setReimbursementType(dto.getReimbursementTypeId());
        if(dto.getPaymentMonth()==null){
                throw new AntException(ResultCode.NOT_FOUND.getResultCode(), "请选择付款方式");
        }
        info.setPaymentMethod(dto.getPaymentMonth().toString());
        info.setInvoicePrice(dto.getPaymentAmount());
        info.setInvoiceNotes(dto.getNotes());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = simpleDateFormat.format(dto.getStartTime());
        String end = simpleDateFormat.format(dto.getDeadline());
        info.setStartTime(time);
        info.setEndTime(end);
        info.setAnnex(dto.getContractAnnex());
        info.setAccountUrgency(dto.getAccountUrgency());
        info.setCreateBy(userInfo.getNameId().toString());
        info.setAccountName(account.getAccountName());
        info.setAccountBank(account.getAccountBank());
        info.setAccountNumber(account.getAccountNumber());
        info.setCreationTime(new Date());
        infoService.save(info);
        return info.getId();
    }

    public void saveHouseSettlement(HouseLease dto) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        HouseSettlement account = new HouseSettlement();
        List<HouseAccount> list = accountService.list(new QueryWrapper<HouseAccount>().eq("parent_id", dto.getId()));
        Date date = DateFormat.addOneMonth(DateUtil.formatDate(dto.getStartTime()), dto.getPaymentMonth());
        account.setEndTime(date);
        account.setParentId(dto.getId());
        account.setHouseAccountId(list.get(0).getId());
        account.setStartTime(dto.getStartTime());
        account.setAmount(dto.getPaymentAmount());
        account.setPaymentMonth(dto.getPaymentMonth().toString());
        account.setPayment(dto.getPaymentMethod());
        account.setHandledBy(dto.getFounder());
        account.setCreateBy(userInfo.getNameId().toString());
        account.setCreateTime(new Date());
        settlementService.save(account);
        HouseLease lease = new HouseLease();
        lease.setFeeDue(date);
        lease.setId(dto.getId());
        this.baseMapper.updateById(lease);
    }

    @Override
    public AuditList selectIsAudit(String processInstanceId, String user_id) {
        HouseLease lease = leaseService.getOne(new QueryWrapper<HouseLease>()
                .eq("process_instance_id", processInstanceId));
        if (lease != null) {
            AuditList parentId = auditListService.getOne(new QueryWrapper<AuditList>()
                    .eq("parent_id", lease.getId())
                    .eq("process_type", "funds")
                    .eq("types", "1")
                    .eq("name_id", user_id));
            if (parentId != null) {
                return parentId;
            }
            return null;
        }
        return null;
    }


    @Override
    public HouseLease findHouseLeaseById(Integer id) {
        if (id == null) {
            throw new AntException(ResultCode.FAILURE.getResultCode(), "参数错误");
        } else {
            HouseLease one = this.baseMapper.selectOne(new QueryWrapper<HouseLease>().eq("id", id));
            if (one == null) {
                throw new AntException(ResultCode.FAILURE.getResultCode(), "数据不存在");
            }
            List<HouseContacts> contactsList = contactsService.list(new QueryWrapper<HouseContacts>()
                    .eq("parent_id", one.getId()));
            one.setHouseContactsList(contactsList);
            List<HouseAccount> accountList = accountService.list(new QueryWrapper<HouseAccount>()
                    .eq("parent_id", one.getId()));
            one.setHouseAccountList(accountList);
            List<HouseSettlement> settlementList = settlementService.list(new QueryWrapper<HouseSettlement>()
                    .eq("parent_id", one.getId()));
            settlementList.stream().forEach(items -> {
                if (items.getAnnex() != null) {
                    List<PurchaserRecordImg> imgList1 = imgService.list(new QueryWrapper<PurchaserRecordImg>()
                            .in("id", items.getAnnex().split(",")));
                    items.setAnnexList(imgList1);
                }
            });
            one.setHouseSettlementList(settlementList);

            if (one.getDepositAnnex() != null) {
                List<PurchaserRecordImg> imgList1 = imgService.list(new QueryWrapper<PurchaserRecordImg>()
                        .in("id", one.getDepositAnnex().split(",")));
                one.setDepositAnnexList(imgList1);
            }

            if (one.getContractAnnex() != null) {
                List<PurchaserRecordImg> imgList = imgService.list(new QueryWrapper<PurchaserRecordImg>()
                        .in("id",
                                Arrays.asList(one.getContractAnnex().split(","))));
                one.setContractAnnexList(imgList);
            }
            return one;
        }
    }

    @Override
    public List<HouseLease> houseLease(Integer id) {
        UserInfo userInfo = (UserInfo) servletContext.getAttribute("userInfo");
        QueryWrapper<HouseLease> wrapper = new QueryWrapper();
        if (userInfo.getRoles() == null) {
            wrapper.in("city_id", userInfo.getCityId()).or().in("create_by", userInfo.getNameId());
        }
        if (userInfo.getRoles() != null && userInfo.getRoles().equals("admin")) {
            wrapper.lambda().eq(HouseLease::getCityId, userInfo.getCityId());
        }
        wrapper.eq("contract_type", id);
        wrapper.eq("take_effect", 1);
        wrapper.orderByDesc("id");
        List<HouseLease> leases = this.baseMapper.selectList(wrapper);
        leases.stream().forEach(items -> {
            if (items.getContractAnnex() != null) {
                List<PurchaserRecordImg> imgList1 = imgService.list(new QueryWrapper<PurchaserRecordImg>()
                        .in("id", items.getContractAnnex().split(",")));
                items.setContractAnnexList(imgList1);
            }
            List<HouseAccount> accountList = accountService.list(new QueryWrapper<HouseAccount>()
                    .eq("parent_id", items.getId()));
            items.setHouseAccountList(accountList);
        });
        return leases;
    }


    private List<Integer> cityList(Integer uid) {
        List<UserCity> user_id = userCityMapper.selectList(new QueryWrapper<UserCity>().eq("user_id", uid));
        List<Integer> list = user_id.stream().map(UserCity::getCityId).collect(Collectors.toList());
        return list;
    }

}
